package com.knowledge.review.jucReview;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author XFW
 * @date 2024/6/21 13:44
 * @Description 原子类刨析
 * AtomicInteger 提供了原子操作如 incrementAndGet()。
 * 不需要同步；原子操作确保了线程安全。
 **/
public class AtomicExample {
    private final AtomicInteger counter = new AtomicInteger(0);

    public void increment() {
        counter.incrementAndGet();
    }

    public int getCounter() {
        return counter.get();
    }

    public int incrementAndGet() {
        return counter.updateAndGet(value -> value + 1);
    }

//    public static void main(String[] args) {
//        AtomicExample example = new AtomicExample();
////        example.increment();
//        // 输出：1
////        System.out.println(example.getCounter());
//
//        // 输出：1
//        System.out.println(example.incrementAndGet());
//        // 输出：2
//        System.out.println(example.incrementAndGet());
//    }

    /*
     * 多线程同时调用 updateAndGet 方法，不会出现竞争条件或数据不一致的问题，因为 compareAndSet
     * 方法确保了每次更新操作的原子性和线程安全性。最终结果是各线程按预期顺序地增加 AtomicInteger 的值。
     * */
    public static void main(String[] args) throws InterruptedException {
        AtomicExample example = new AtomicExample();

        /**
         * 单线程执行
         */
//        // 直接获取值，输出：1
//        System.out.println(example.getCounter());
//        // 获取新增的值 输出：1
//        System.out.println(example.incrementAndGet());
//        // 获取新增的值 输出：2
//        System.out.println(example.incrementAndGet());

        int numberOfThreads = 10;
        Thread[] threads = new Thread[numberOfThreads];

        for (int i = 0; i < numberOfThreads; i++) {
            threads[i] = new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    System.out.println(example.incrementAndGet());
                }
            });
        }

        for (Thread thread : threads) {
            thread.start();
        }

        for (Thread thread : threads) {
            thread.join();
        }

        System.out.println("Final value: " + example.counter.get());
    }
}
